/*
 * Copyright © 2024-2025 Wenze Wei
 *
 * This file is part of StadionOS.
 *
 * This Source Code Form is subject to the terms of the GNU General Public License, v. 2.0.
 * You can obtain a copy of the GPL at
 * https://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 */

#include "../include/math.h"

/**
 * @brief Calculates the inverse tangent of a double.
 *
 * This function returns the inverse tangent of the given double value.
 * It handles special cases where the input is 0 or outside the range [-1, 1].
 *
 * @param x The double value.
 * @return double The inverse tangent of x.
 */
double Satan(double x) {
    if (x == 0)
        return DNAN;

    return SAtan(x);
}

/**
 * @brief Calculates the inverse tangent of a double using a series expansion.
 *
 * This function returns the inverse tangent of the given double value using a series expansion.
 * It handles special cases where the input is greater than 1 or less than -1.
 *
 * @param x The double value.
 * @return double The inverse tangent of x.
 */
double SAtan(double x) {
    if (x > 1.0)
        return DM_PI / 2 - SAtan(1.0 / x);

    if (x < -1.0)
        return -DM_PI / 2 - SAtan(1.0 / x);

    double result = 0.0;
    double term = x;
    int n = 1;

    while (term != 0.0) {
        result += term;
        n += 2;
        term *= -x * x / (n * (n - 1));
    }

    return result;
}
